Wiki

Clone wiki

Milandr / Непрерывная выдача DAC + DMA

Конфиг переферии

ЦАП

#!c
    RST_CLK_PCLKcmd(RST_CLK_PCLK_DAC, ENABLE);
    DAC_DeInit();
    DAC_Init(DAC_SYNC_MODE_Independent, DAC1_AVCC, DAC2_AVCC);  
    DAC2_Cmd(ENABLE);   

Таймер для тактирования ДМА

#!c

    /* TIMER2 Configuration ------------------------------------------------- DAC out 2400hz */
    RST_CLK_PCLKcmd(RST_CLK_PCLK_TIMER2, ENABLE);
    TIMER_DeInit(MDR_TIMER2);                                               // Deinitializes the TIMERx peripheral registers to their default reset values.
    TIMER_CntStructInit(&TIMER_CntInitStructure);                           // Fills each TIMER_CntInitStruct member with its default value.
    TIMER_CntInitStructure.TIMER_Prescaler = 0;
    TIMER_CntInitStructure.TIMER_Period = 80000000/2400/512-1;
    TIMER_CntInit(MDR_TIMER2, &TIMER_CntInitStructure);                     // Initializes the TIMERx Counter peripheral according to the specified parameters in the TIMER_CntInitStruct.

    TIMER_BRGInit(MDR_TIMER2,TIMER_HCLKdiv1);                               /* Enable TIMER1 clock */
    TIMER_Cmd(MDR_TIMER2, ENABLE);                                          // Enables or disables the specified TIMER peripheral.

    TIMER_DMACmd(MDR_TIMER2, TIMER_STATUS_CNT_ARR, ENABLE);

ДМА для передачи из памяти в ЦАП

#!c
        /* DMA Timer2 */
    /* Set Primary Control Data */
    DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)(&SinusArray[0]);
    DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)&(MDR_DAC->DAC2_DATA);
    DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncHalfword;
    DMA_PriCtrlStr.DMA_DestIncSize = DMA_DestIncNo;
    DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_PriCtrlStr.DMA_Mode = DMA_Mode_PingPong;
    DMA_PriCtrlStr.DMA_CycleSize = 256;
    DMA_PriCtrlStr.DMA_NumContinuous = DMA_Transfers_1;
    DMA_PriCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged;
    DMA_PriCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged;

    /* Set Alternate Control Data */
    DMA_AltCtrlStr.DMA_SourceBaseAddr = (uint32_t)(&SinusArray[256]);
    DMA_AltCtrlStr.DMA_DestBaseAddr   = (uint32_t)&(MDR_DAC->DAC2_DATA);
    DMA_AltCtrlStr.DMA_SourceIncSize = DMA_SourceIncHalfword;
    DMA_AltCtrlStr.DMA_DestIncSize = DMA_DestIncNo;
    DMA_AltCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_AltCtrlStr.DMA_Mode = DMA_Mode_PingPong;
    DMA_AltCtrlStr.DMA_CycleSize = 256;
    DMA_AltCtrlStr.DMA_NumContinuous = DMA_Transfers_1;
    DMA_AltCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged;
    DMA_AltCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged;

    /* Set Channel Structure */
    DMA_InitStr.DMA_PriCtrlData = &DMA_PriCtrlStr;
    DMA_InitStr.DMA_AltCtrlData = &DMA_AltCtrlStr;
    DMA_InitStr.DMA_Priority = DMA_Priority_Default;
    DMA_InitStr.DMA_UseBurst = DMA_BurstClear;
    DMA_InitStr.DMA_SelectDataStructure = DMA_CTRL_DATA_PRIMARY;
    DMA_Init(DMA_Channel_TIM2, &DMA_InitStr);                                       // Initializes the DMA Channel according to the specified parameters in the DMA_InitStruct.

    DMA_Cmd(DMA_Channel_TIM2, ENABLE);                                              // Enables or disables the specified DMA Channel.

Прерывания

#!c
void DMA_IRQHandler(void)
{
    if (!(DMA_ControlTable[DMA_Channel_TIM2].DMA_Control & 0x3))                                            // DMA_Channel_TIM2 PRIMARY
    {
        /* CHNL_PRI_ALT_SET = 1 Используется альтернативная конфигурация (получены значения с основной конфигурации) */
        /* Обновляются значения в основной конфигурации */
        if (((MDR_DMA->CHNL_PRI_ALT_SET >> DMA_Channel_TIM2) & 1) == 1)                     
        {
            DMA_ControlTable[DMA_Channel_TIM2].DMA_Control |= ((256 - 1) << 4) | DMA_Mode_PingPong;
        }
        DMA_Cmd(DMA_Channel_TIM2, ENABLE);
    }
    if (!(DMA_ControlTable[DMA_Channel_TIM2+32].DMA_Control & 0x3))                                         // DMA_Channel_TIM2 ALTERNATIVE
    {
        /* CHNL_PRI_ALT_SET = 0 Используется основная конфигурация (получены значения с альтернативной конфигурации) */
        /* Обновляются значения в альтернативной конфигурации */
        if (((MDR_DMA->CHNL_PRI_ALT_SET >> DMA_Channel_TIM2) & 1) == 0)                         
        {
            DMA_ControlTable[DMA_Channel_TIM2+32].DMA_Control |= ((256 - 1) << 4) | DMA_Mode_PingPong;
        }
        DMA_Cmd(DMA_Channel_TIM2, ENABLE);
    }

}

Updated